package com.wang.back.servlet;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wang.common.pojo.ApiResponse;
import com.wang.common.servlet.BaseServlet;
import com.wang.common.util.ConstatFinalUtil;
import com.wang.common.util.PageInfoUtil;
import com.wang.common.util.PoiUtil;
import com.wang.users.pojo.AQuesDesc;
import com.wang.users.pojo.AQuesDetail;
import com.wang.users.pojo.AUsers;
import com.wang.users.service.IQuesDbService;
import com.wang.users.service.impl.QuesDbServiceImpl;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * 第二个Servlet 只存储和管理员息息相关的信息 登陆后的操作
 *
 * @author wangshMac
 */
@WebServlet(urlPatterns = "/back/QuesBackServlet")
@MultipartConfig
public class QuesBackServlet extends BaseServlet {
    private IQuesDbService quesDbService;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        this.quesDbService = new QuesDbServiceImpl();
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /* 接收参数 */
        String method = request.getParameter("method");
        if ("quesDescList".equalsIgnoreCase(method)) {
            quesDescList(request, response);
        } else if ("quesDescInsert".equalsIgnoreCase(method)) {
            quesDescInsert(request, response);
        } else if ("quesDescInsertSubmit".equalsIgnoreCase(method)) {
            quesDescInsertSubmit(request, response);
        } else if ("quesDescUpdate".equalsIgnoreCase(method)) {
            quesDescUpdate(request, response);
        } else if ("quesDescUpdateSubmit".equalsIgnoreCase(method)) {
            quesDescUpdateSubmit(request, response);
        }else if ("quesDetailList".equalsIgnoreCase(method)) {
            quesDetailList(request, response);
        } else if ("quesDetailInsert".equalsIgnoreCase(method)) {
            quesDetailInsert(request, response);
        } else if ("quesDetailInsertSubmit".equalsIgnoreCase(method)) {
            quesDetailInsertSubmit(request, response);
        } else if ("quesDetailUpdate".equalsIgnoreCase(method)) {
            quesDetailUpdate(request, response);
        } else if ("quesDetailUpdateSubmit".equalsIgnoreCase(method)) {
            quesDetailUpdateSubmit(request, response);
        } else if ("quesDetailExport".equalsIgnoreCase(method)) {
            quesDetailExport(request, response);
        }
    }

    private void quesDetailExport(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 分页信息 */
        PageInfoUtil pageInfoUtil = this.proccedPageInfo(request);
        /* 搜索条件,生成公共的搜索条件 */
        Map<String, Object> condMap = this.proccedSearch(request);

        String usersId = request.getParameter("usersId");
        condMap.put("usersId", usersId);
        request.setAttribute("usersId", usersId);

        String quesId = request.getParameter("quesId");
        condMap.put("quesId", quesId);
        request.setAttribute("quesId", quesId);

        /* 查询数据库
         * 所有的数据以JSON的形式返回
         *  */
        ApiResponse<AQuesDetail> apiResponse = this.quesDbService.findCondListQuesDetailService(pageInfoUtil, condMap);
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());

        JSONObject responseJson = (JSONObject) request.getAttribute("response");

        JSONObject dataJson = responseJson.getJSONObject("data");
        JSONArray listArr = dataJson.getJSONArray("list");
        List<Map<String, Object>> resultList = new ArrayList<>();

        for (Object o : listArr) {
            JSONObject data = (JSONObject) o;
            Map<String,Object> dataTempMap = new HashMap<>();
            for (Map.Entry<String, Object> me : data.entrySet()) {
                String key = me.getKey();
                Object val = me.getValue();
                dataTempMap.put(key, val);
            }

            JSONObject users = data.getJSONObject("users");
            JSONObject ques = data.getJSONObject("ques");

            dataTempMap.put("usersName", users.getString("nickName"));
            dataTempMap.put("quesDescName", ques.getString("name"));

            resultList.add(dataTempMap);
        }

        // 2.设置返回数据的响应类型为(二进制)流类型
        response.setContentType("application/octet-stream");
        // 3.设置响应头信息 告诉浏览器以何种方式处理后台返回的数据；attachment 表示浏览器以下载的形式打开文件
        // 文件名有中文需要单独编码
        String encodedFilename = URLEncoder.encode("quesDetail_list.xls", "UTF-8");
        response.setHeader("Content-Disposition", "inline;filename=" + encodedFilename);

        InputStream is = PoiUtil.class.getClassLoader().getResourceAsStream("template/quesDetail_list.xls");
        ServletOutputStream os = response.getOutputStream();
        this.poiUtil.writeExcelModel(is, resultList, os);
    }

    /**
     * 题目概要列表
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDescList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDescList.jsp";

        /* 分页信息 */
        PageInfoUtil pageInfoUtil = this.proccedPageInfo(request);
        /* 搜索条件,生成公共的搜索条件 */
        Map<String, Object> condMap = this.proccedSearch(request);

        String usersId = request.getParameter("usersId");
        condMap.put("usersId", usersId);
        request.setAttribute("usersId", usersId);

        /* 查询数据库
         * 所有的数据以JSON的形式返回
         *  */
        ApiResponse<AQuesDesc> apiResponse = this.quesDbService.findCondListQuesDescService(pageInfoUtil, condMap);
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());

        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开添加页面)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDescInsert(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDescInsert.jsp";
        ApiResponse<AQuesDesc> apiResponse = new ApiResponse<>();
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());
        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开添加提交)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDescInsertSubmit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String content = request.getParameter("content");
        String status = request.getParameter("status");

        /* 接收参数 */
        AQuesDesc quesDesc = new AQuesDesc();

        AUsers usersSess = (AUsers) this.findObjfromSession(request, "users");
        quesDesc.setUsersId(usersSess.getId());
        quesDesc.setName(name);
        quesDesc.setContent(content);
        quesDesc.setStatus(Byte.parseByte(status));
        ApiResponse<Object> dbResponse = this.quesDbService.saveOneQuesDescService(quesDesc);
        this.printOut(dbResponse.toJSON().toJSONString(), response);
    }

    /**
     * 题目概要添加(打开更新页面)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDescUpdate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDescInfo.jsp";
        String id = request.getParameter("id");
        Map<String,Object> condMap = new HashMap<>();
        condMap.put("id", id);
        ApiResponse<AQuesDesc> apiResponse = this.quesDbService.findOneQuesDescService(condMap);
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());
        String operType = request.getParameter("operType");
        if ("updateInfo".equalsIgnoreCase(operType)) {
            /* 修改个人信息 */
            this.path = "/WEB-INF/jsp/back/ques/quesDescUpdate.jsp";
        }
        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开更新提交)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDescUpdateSubmit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");
        Map<String,Object> condMap = new HashMap<>();
        condMap.put("id", id);
        ApiResponse<AQuesDesc> dbResQuesDescService = this.quesDbService.findOneQuesDescService(condMap);
        /* 接收参数 */
        AQuesDesc quesDesc = dbResQuesDescService.getDataOneJava();

        boolean updateFlag = false;
        String operType = request.getParameter("operType");
        if ("updateInfo".equalsIgnoreCase(operType)) {
            String name = request.getParameter("name");
            String content = request.getParameter("content");
            String status = request.getParameter("status");

            quesDesc.setName(name);
            quesDesc.setContent(content);
            quesDesc.setStatus(Byte.parseByte(status));
            updateFlag = true;
        }
        ApiResponse<Object> dbResponse = new ApiResponse<>();
        if (updateFlag) {
            dbResponse = this.quesDbService.updateOneQuesDescService(quesDesc);
        }
        this.printOut(dbResponse.toJSON().toJSONString(), response);
    }

    /**
     * 题目概要列表
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDetailList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDetailList.jsp";

        /* 分页信息 */
        PageInfoUtil pageInfoUtil = this.proccedPageInfo(request);
        /* 搜索条件,生成公共的搜索条件 */
        Map<String, Object> condMap = this.proccedSearch(request);

        String usersId = request.getParameter("usersId");
        condMap.put("usersId", usersId);
        request.setAttribute("usersId", usersId);

        String quesId = request.getParameter("quesId");
        condMap.put("quesId", quesId);
        request.setAttribute("quesId", quesId);

        /* 查询数据库
         * 所有的数据以JSON的形式返回
         *  */
        ApiResponse<AQuesDetail> apiResponse = this.quesDbService.findCondListQuesDetailService(pageInfoUtil, condMap);
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());

        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开添加页面)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDetailInsert(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDetailInsert.jsp";
        ApiResponse<AQuesDetail> apiResponse = new ApiResponse<>();
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());
        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开添加提交)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDetailInsertSubmit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String quesId = request.getParameter("quesId");
        String name = request.getParameter("name");
        String content = request.getParameter("content");

        /* 接收参数 */
        AQuesDetail quesDetail = new AQuesDetail();

        AUsers usersSess = (AUsers) this.findObjfromSession(request, "users");
        quesDetail.setUsersId(usersSess.getId());
        quesDetail.setQuesId(Integer.parseInt(quesId));
        quesDetail.setName(name);
        quesDetail.setContent(content);
        ApiResponse<Object> dbResponse = this.quesDbService.saveOneQuesDetailService(quesDetail);
        this.printOut(dbResponse.toJSON().toJSONString(), response);
    }

    /**
     * 题目概要添加(打开更新页面)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDetailUpdate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 准备路径 */
        this.path = "/WEB-INF/jsp/back/ques/quesDetailInfo.jsp";
        String id = request.getParameter("id");
        Map<String,Object> condMap = new HashMap<>();
        condMap.put("id", id);
        ApiResponse<AQuesDetail> apiResponse = this.quesDbService.findOneQuesDetailService(condMap);
        /* 将结果存储到Request中 */
        request.setAttribute("response", apiResponse.toJSON());
        String operType = request.getParameter("operType");
        if ("updateInfo".equalsIgnoreCase(operType)) {
            /* 修改个人信息 */
            this.path = "/WEB-INF/jsp/back/ques/quesDetailUpdate.jsp";
        }else if ("audit".equalsIgnoreCase(operType)) {
            /* 修改个人信息 */
            this.path = "/WEB-INF/jsp/back/ques/quesDetailAudit.jsp";
        }
        /* 页面跳转 */
        request.getRequestDispatcher(path).forward(request, response);
    }

    /**
     * 题目概要添加(打开更新提交)
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void quesDetailUpdateSubmit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");
        Map<String,Object> condMap = new HashMap<>();
        condMap.put("id", id);
        ApiResponse<AQuesDetail> dbResQuesDetailService = this.quesDbService.findOneQuesDetailService(condMap);
        /* 接收参数 */
        AQuesDetail quesDetail = dbResQuesDetailService.getDataOneJava();

        boolean updateFlag = false;
        String operType = request.getParameter("operType");
        if ("updateInfo".equalsIgnoreCase(operType)) {
            String name = request.getParameter("name");
            String content = request.getParameter("content");
            String status = request.getParameter("status");

            quesDetail.setName(name);
            quesDetail.setContent(content);
            quesDetail.setStatus(Byte.parseByte(status));

            Part filePath = request.getPart("filePath");
            String fileName = filePath.getSubmittedFileName();
            InputStream is = filePath.getInputStream();

            /* 上传文件的相对路径 */
            String uploadFile = ConstatFinalUtil.CONFIG_JSON.getString("website.uploadFile");
            /* 存储的是网址的绝对路径 */
            String souPath = quesDetail.getFilePath() ;
            /* 真实路径 */
            String truePath = ConstatFinalUtil.CONFIG_JSON.getString("website.truePath");
            String tarRelaPath = uploadFile + "/" + this.dateFormatUtil.dateStr(new Date()) + "/" + UUID.randomUUID().toString() +
                    fileName.substring(fileName.lastIndexOf("."), fileName.length());
            File tarTrueFile = new File(truePath + tarRelaPath);

            /* 创建父目录 */
            if(!tarTrueFile.getParentFile().exists())
            {
                tarTrueFile.getParentFile().mkdirs();
            }
            quesDetail.setName(fileName);
            quesDetail.setFilePath(tarRelaPath);

            FileOutputStream fos = new FileOutputStream(tarTrueFile);
            /* 复制文件 */
            boolean flag = this.fileUtil.copyFile(is, fos);
            if(flag)
            {
                if(souPath != null && !"".equalsIgnoreCase(souPath))
                {
                    /* 相对路径 */
                    File souFile = new File(truePath + souPath);
                    if(!souFile.delete())
                    {
                        ConstatFinalUtil.SYS_LOGGER.error("删除原始文件失败:原始文件路径:{}",souFile.getAbsolutePath());
                    }
                }
            }

            updateFlag = true;
        } else if ("audit".equalsIgnoreCase(operType)) {
            String auditStatus = request.getParameter("auditStatus");
            quesDetail.setAuditStatus(Byte.parseByte(auditStatus));
            quesDetail.setAuditTime(new Date());
            updateFlag = true;
        }
        ApiResponse<Object> dbResponse = new ApiResponse<>();
        if (updateFlag) {
            dbResponse = this.quesDbService.updateOneQuesDetailService(quesDetail);
        }
        this.printOut(dbResponse.toJSON().toJSONString(), response);
    }
}
